from faker import Faker
import random
from datetime import datetime, timedelta
from dateutil.relativedelta import relativedelta
from data_mock.utils import FileUtil, MysqlUtils_AI

fake = Faker('zh_CN')

# ========== 肿瘤数据配置 ==========
TUMOR_DIAGNOSIS = {
    'C34.90': ('肺恶性肿瘤', ['小细胞癌', '腺癌', '鳞癌']),
    'C16.9': ('胃恶性肿瘤', ['腺癌', '印戒细胞癌']),
    'C50.9': ('乳腺恶性肿瘤', ['浸润性导管癌', '小叶癌']),
    'C61': ('前列腺恶性肿瘤', ['腺癌']),
    'C18.9': ('结肠恶性肿瘤', ['腺癌', '粘液腺癌']),
    'C25.9': ('胰腺恶性肿瘤', ['导管腺癌']),
    'C53.9': ('宫颈恶性肿瘤', ['鳞癌']),
    'C64.9': ('肾恶性肿瘤', ['透明细胞癌']),
    'C73': ('甲状腺恶性肿瘤', ['乳头状癌'])
}

# ========== 基础数据配置 ==========
HOSPITAL = {
    'code': 'H12345678',
    'name': '国家肿瘤医学中心'
}

DEPARTMENTS = ['肿瘤内科', '肿瘤外科', '放疗科', '血液科']
PAYMENT_TYPES = ['城镇职工医保', '城乡居民医保', '新农合', '商业保险', '自费']
ADMISSION_TYPES = ['急诊', '门诊', '转院']
DISCHARGE_STATUSES = ['治愈', '好转', '未愈', '死亡']
BLOOD_TYPES = ['A', 'B', 'AB', 'O']
RH_TYPES = ['阳性', '阴性']
MARITAL_STATUSES = ['未婚', '已婚', '离异', '丧偶']
OCCUPATIONS = ['公务员', '职员', '工人', '农民', '学生', '退休']
NATIONALITIES = ['中国', '美国', '日本', '韩国']
ETHNIC_GROUPS = ['汉族', '回族', '满族', '蒙古族']


# ========== 时间范围配置 ==========
def generate_DAY_RANGE(start_day, end_day):
    start = datetime.strptime(start_day, "%Y-%m-%d")
    end = datetime.strptime(end_day, "%Y-%m-%d")
    days = []
    current = start
    while current <= end:
        days.append(current.strftime("%Y-%m-%d"))
        current += relativedelta(days=1)
    return days


DAY_RANGE = generate_DAY_RANGE("2025-08-01", "2025-08-03")


def generate_records_per_day(day: str):
    date_obj = datetime.strptime(day, '%Y-%m-%d')
    return 8 if date_obj.day % 2 == 0 else 6


# ========== 核心生成函数 ==========
def generate_tumor_medical_records():
    """生成肿瘤病案首页数据"""
    sql_statements = []
    total_records = 0

    patient_id_counter = 1001  # 与b02_1保持一致
    visit_sn_counter = 1001

    for month in DAY_RANGE:
        records_this_month = generate_records_per_day(month)
        print(f"正在生成 {month} 月病案首页（{records_this_month}条）...")

        for i in range(1, records_this_month + 1):

            # 随机选择肿瘤诊断
            diag_code, (diag_name, subtypes) = random.choice(list(TUMOR_DIAGNOSIS.items()))
            stage = random.choice(['Ⅰ期', 'Ⅱ期', 'Ⅲ期', 'Ⅳ期'])
            full_diag_name = f"{diag_name}({random.choice(subtypes) if subtypes else ''}){stage}"

            # 生成时间信息
            admission_date = fake.date_time_between(
                start_date=datetime.strptime(month, "%Y-%m-%d"),
                end_date=datetime.strptime(month, "%Y-%m-%d") + relativedelta(months=1)
            )
            discharge_date = admission_date + timedelta(days=random.randint(3, 30))

            # 生成费用信息
            total_cost = random.randint(10000, 50000)
            self_pay = round(total_cost * random.uniform(0.1, 0.5))

            data = {
                'yy_upload_status': 0,
                'yy_etl_time': datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
                'yy_upload_time': None,
                'yy_batch_time': month,
                'yy_record_batch_id': f"BATCH{month}_{i}",
                'yy_backfill_time': None,
                'yy_backfill_status': None,
                'A01': HOSPITAL['code'],
                'A02': HOSPITAL['name'],
                'patient_id': f"PT{patient_id_counter}",
                'visit_sn': f"VIS{visit_sn_counter}",
                'A48': f"MR{random.randint(100000, 999999)}",
                'A49': str(random.randint(1, 5)),
                'B12': admission_date.strftime('%Y-%m-%d %H:%M:%S'),
                'B15': discharge_date.strftime('%Y-%m-%d %H:%M:%S'),
                'A46C': random.choice(PAYMENT_TYPES),
                'A11': fake.name(),
                'A12C': random.choice(['男', '女']),
                'A13': fake.date_of_birth(minimum_age=30, maximum_age=80).strftime('%Y-%m-%d'),
                'A15C': random.choice(NATIONALITIES),
                'A21C': random.choice(MARITAL_STATUSES),
                'A38C': random.choice(OCCUPATIONS),
                'A19C': random.choice(ETHNIC_GROUPS),
                'A20N': '居民身份证',
                'A20': fake.ssn(),
                'A22': fake.city() + fake.street_address(),
                'A23C': fake.province(),
                'A26': fake.address(),
                'A32': fake.name(),
                'A33C': random.choice(['配偶', '子女', '父母', '其他亲属']),
                'A34': fake.address(),
                'A35': fake.phone_number(),
                'B38': random.choice(['是', '否']),
                'B11C': random.choice(ADMISSION_TYPES),
                'B13C': random.choice(DEPARTMENTS),
                'B14': random.choice(['东区病房', '西区病房']),
                'B21C': random.choice(DEPARTMENTS),
                'B16C': random.choice(DEPARTMENTS),
                'B17': random.choice(['东区病房', '西区病房']),
                'B20': str((discharge_date - admission_date).days),
                'C01C': diag_code,
                'C02N': full_diag_name,
                'F01': random.choice(['稳定', '危重', '一般']),
                'F02C': diag_code,
                'F03N': full_diag_name,
                'F04': (admission_date + timedelta(days=2)).strftime('%Y-%m-%d'),
                'C03C': diag_code,
                'C04N': full_diag_name,
                'C05C': random.choice(['临床诊断', '病理确诊']),
                'F05': random.choice(DISCHARGE_STATUSES),
                # 生成3个其他诊断
                'C06x01C': 'E11',
                'C07x01N': '2型糖尿病',
                'C08x01C': random.choice(['入院即有', '住院期间发生']),
                'F06x01': random.choice(DISCHARGE_STATUSES),
                'C06x02C': 'I10',
                'C07x02N': '原发性高血压',
                'C08x02C': random.choice(['入院即有', '住院期间发生']),
                'F06x02': random.choice(DISCHARGE_STATUSES),
                'C06x03C': 'J18',
                'C07x03N': '肺炎',
                'C08x03C': random.choice(['入院即有', '住院期间发生']),
                'F06x03': random.choice(DISCHARGE_STATUSES),
                'C26C': random.choice(BLOOD_TYPES),
                'C27C': random.choice(RH_TYPES),
                'C14x01C': random.choice(['32.29', '43.5', '60.5']),
                'C15x01N': random.choice(['肺叶切除术', '胃大部切除术', '前列腺根治术']),
                'C16x01': (admission_date + timedelta(days=random.randint(1, 5))).strftime('%Y-%m-%d'),
                'C17x01': random.choice(['一级', '二级', '三级', '四级']),
                'F13': str(random.randint(60, 300)),
                'C18x01': fake.name(),
                'C19x01': fake.name(),
                'C20x01': fake.name(),
                'C21x01C': random.choice(['甲级', '乙级', '丙级']),
                'C22x01C': random.choice(['全麻', '硬膜外麻醉', '局麻']),
                'F15': random.choice(['Ⅰ级', 'Ⅱ级', 'Ⅲ级', 'Ⅳ级']),
                'C23x01': fake.name(),
                'D01': str(total_cost),
                'D09': str(self_pay),
                'D11': str(round(total_cost * 0.1)),
                'D12': str(round(total_cost * 0.05)),
                'D13': str(round(total_cost * 0.03)),
                'D14': str(round(total_cost * 0.02)),
                'D15': str(round(total_cost * 0.08)),
                'D16': str(round(total_cost * 0.12)),
                'D17': str(round(total_cost * 0.1)),
                'D18': str(round(total_cost * 0.05)),
                'D19': str(round(total_cost * 0.15)),
                'D19x01': str(round(total_cost * 0.03)),
                'D20': str(round(total_cost * 0.25)),
                'D20x01': str(round(total_cost * 0.05)),
                'D20x02': str(round(total_cost * 0.15)),
                'D21': str(round(total_cost * 0.02)),
                'D22': str(round(total_cost * 0.01)),
                'D23': str(round(total_cost * 0.3)),
                'D23x01': str(round(total_cost * 0.05)),
                'D24': str(round(total_cost * 0.05)),
                'D25': str(round(total_cost * 0.03)),
                'D26': str(round(total_cost * 0.02)) if random.random() > 0.7 else '0',
                'D27': str(round(total_cost * 0.01)) if random.random() > 0.8 else '0',
                'D28': str(round(total_cost * 0.01)) if random.random() > 0.8 else '0',
                'D29': str(round(total_cost * 0.01)) if random.random() > 0.8 else '0',
                'D30': str(round(total_cost * 0.01)) if random.random() > 0.8 else '0',
                'D31': str(round(total_cost * 0.02)),
                'D32': str(round(total_cost * 0.02)),
                'D33': str(round(total_cost * 0.03)),
                'D34': str(round(total_cost * 0.05)),
                'F21': random.choice(['无', '轻度', '中度', '重度']),
                'F22': str(random.randint(0, 4)),
                'F23': str(random.randint(0, 6)),
                'F24': str(random.randint(0, 2)),
                'F25': str(random.randint(0, 2)),
                'F26': random.choice(['是', '否']),
                'B36C': random.choice(['有', '无']),
                'B37': random.choice(['继续治疗', '复查', '康复']),
                'B34C': random.choice(['医嘱离院', '自动离院', '转院']),
                'B35': random.choice(['某某社区卫生服务中心', '某某乡镇卫生院'])
            }

            patient_id_counter += 1
            visit_sn_counter+=1
            sql = _generate_sql('b04_1_n', data)
            sql_statements.append(sql)
            total_records += 1

    return sql_statements, total_records


def _generate_sql(table, data):
    """生成SQL插入语句"""
    columns = []
    values = []
    for k, v in data.items():
        columns.append(f'`{k}`')
        if v is None:
            values.append('NULL')
        elif isinstance(v, (int, float)):
            values.append(str(v))
        else:
            escaped_value = str(v).replace("'", "''")
            values.append(f"'{escaped_value}'")
    return f"INSERT INTO `{table}` ({', '.join(columns)}) VALUES ({', '.join(values)});"


# ========== 执行生成 ==========
if __name__ == "__main__":
    records,total_count = generate_tumor_medical_records()
    # 写入数据库
    MysqlUtils_AI.insert_data_to_hub(records, 'b04_1_n')
    # 或写入 SQL 文件
    # FileUtil.generate_sql_file(records, "b03_1_inpatient_records.sql")
